﻿using System;
using System.Data.Common;
using Development.Tools;

namespace Development.DbData
{
    /// <summary>
    /// 数据库提供者
    /// </summary>
    public class DbProvider
    {
        protected DbConnection m_conn = null;
        private DbDataReader m_reader = null;
        public DbConnection Conn { get { return m_conn; } }
        private int m_col = 0;
        private String m_connectionString;


        public DbProvider(string connectionString)
        {
            m_connectionString = connectionString;
        }

        public bool Open()
        {
            if (m_conn == null)
            {
                try
                {
                    if (string.IsNullOrEmpty(m_connectionString))
                    {
                        return false;
                    }
                    m_conn = CreateConnection(m_connectionString);
                    if (m_conn == null)
                    {
                        return false;
                    }
                    m_conn.Open();
                }
                catch (Exception)
                {
                //    Log.WriteLog(ELogLevel.LOG_ERROR, string.Format("{0};info[instance:{1}methed:{2}stack:{3}", e.Message, e.Source, e.TargetSite.Name, e.StackTrace));
                    return false;
                }
            }
            return true;
        }

        protected virtual DbConnection CreateConnection(string connString)
        {
            return null;
        }

        protected virtual DbCommand CreateCommand(string sql)
        {
            return null;
        }

        public virtual DbParameter CreateParameter(string paramName,int paramType,object paramValue)
        {
            return null;
        }

        public void Close()
        {
            if (m_conn != null)
            {
                m_conn.Close();
                m_conn = null;
            }
        }

        public bool IsTableExist(string tableName)
        {
            string sql = string.Format("select count(*) from {0}", tableName);
            DbCommand cm = CreateCommand(sql);
            bool isExist = false;
            try
            {
                cm.ExecuteNonQuery();
                isExist = true;
            }
            catch (Exception)
            {
                isExist = false;
            }
            cm.Dispose();
            return isExist;
        }

        public int ExecuteNonQuery(string sql)
        {
            int ret = 0;
            DbCommand cm = CreateCommand(sql);
            try
            {
                ret = cm.ExecuteNonQuery();
            }
            catch (Exception e)
            {
                Log.WriteLog(ELogLevel.LOG_ERROR, string.Format("{0};info[instance:{1}methed:{2}stack:{3}", e.Message, e.Source, e.TargetSite.Name, e.StackTrace));
            }
            cm.Dispose();
            return ret;
        }

        public int ExecuteNonQuery(string sql, params DbParameter[] Params)
        {
            int ret = 0;
            DbCommand cm = CreateCommand(sql);
            foreach (DbParameter par in Params)
            {
                cm.Parameters.Add(par);
            }
            try
            {
                ret = cm.ExecuteNonQuery();
            }
            catch (Exception e)
            {
                Log.WriteLog(ELogLevel.LOG_ERROR, string.Format("{0};info[instance:{1}methed:{2}stack:{3}", e.Message, e.Source, e.TargetSite.Name, e.StackTrace));
            }
            cm.Dispose();
            return ret;
        }

        public object ExecuteScalar(string sql)
        {
            object ret = null;
            DbCommand cm = CreateCommand(sql);
            try
            {
                ret = cm.ExecuteScalar();
            }
            catch (Exception e)
            {
                Log.WriteLog(ELogLevel.LOG_ERROR, string.Format("{0};info[instance:{1}methed:{2}stack:{3}", e.Message, e.Source, e.TargetSite.Name, e.StackTrace));
            }
            cm.Dispose();
            return ret;
        }

        public bool ExecuteQuery(string sql)
        {
            try
            {
                DbCommand cm = CreateCommand(sql);
                m_reader = cm.ExecuteReader();
                cm.Dispose();
            }
            catch (Exception e)
            {
                Log.WriteLog(ELogLevel.LOG_ERROR, string.Format("{0};info[instance:{1}methed:{2}stack:{3}", e.Message, e.Source, e.TargetSite.Name, e.StackTrace));
                EndExecuteQuery();
                return false;
            }
            return true;
        }

        public void EndExecuteQuery()
        {
            if (m_reader != null)
            {
                m_col = 0;
                m_reader.Close();
                m_reader = null;
            }
        }
        public bool Read()
        {
            bool ret = false;
            try
            {

                if (m_reader != null)
                {
                    m_col = 0;
                    ret = m_reader.Read();
                }
            }
            catch (Exception e)
            {
                Log.WriteLog(ELogLevel.LOG_ERROR, string.Format("{0};info[instance:{1}methed:{2}stack:{3}", e.Message, e.Source, e.TargetSite.Name, e.StackTrace));
                EndExecuteQuery();
                return ret;
            }
            return ret;
        }
        public object Read(int index)
        {
            object val = null;
            try
            {
               val = m_reader[index];
            }
            catch(Exception e)
            {
                EndExecuteQuery();
                Log.WriteLog(ELogLevel.LOG_ERROR, string.Format("{0};info[instance:{1}methed:{2}stack:{3}", e.Message, e.Source, e.TargetSite.Name, e.StackTrace));
            }
            return val;
        }

        public object Read(string colName)
        {
            object val = null;
            try
            {
                val = m_reader[colName];
            }
            catch (Exception e)
            {
                EndExecuteQuery();
                Log.WriteLog(ELogLevel.LOG_ERROR, string.Format("{0};info[instance:{1}methed:{2}stack:{3}", e.Message, e.Source, e.TargetSite.Name, e.StackTrace));
            }
            return val;
        }

        public DbProvider Read(ref byte val)
        {
            try
            {
                val = (byte)m_reader[m_col];
                m_col++;
            }
            catch (Exception e)
            {
                EndExecuteQuery();
                Log.WriteLog(ELogLevel.LOG_ERROR, string.Format("{0};info[instance:{1}methed:{2}stack:{3}", e.Message, e.Source, e.TargetSite.Name, e.StackTrace));
            }
            return this;
        }

        public DbProvider Read(out byte[] val)
        {
            val = null;
            try
            {
                if (m_reader[m_col].Equals(DBNull.Value))
                {
                    val = new byte[10];
                }
                else
                {
                    val = (byte[])m_reader[m_col];
                }
                m_col++;
            }
            catch (Exception e)
            {
                EndExecuteQuery();
                Log.WriteLog(ELogLevel.LOG_ERROR, string.Format("{0};info[instance:{1}methed:{2}stack:{3}", e.Message, e.Source, e.TargetSite.Name, e.StackTrace));
            }
            return this;
        }

        public DbProvider Read(ref short val)
        {
            try
            {
                val = (short)m_reader[m_col];
                m_col++;
            }
            catch (Exception e)
            {
                EndExecuteQuery();
                Log.WriteLog(ELogLevel.LOG_ERROR, string.Format("{0};info[instance:{1}methed:{2}stack:{3}", e.Message, e.Source, e.TargetSite.Name, e.StackTrace));
            }
            return this;
        }

        public DbProvider Read(ref int val)
        {
            try
            {
                val = (int)m_reader[m_col];
                m_col++;
            }
            catch (Exception e)
            {
                EndExecuteQuery();
                Log.WriteLog(ELogLevel.LOG_ERROR, string.Format("{0};info[instance:{1}methed:{2}stack:{3}", e.Message, e.Source, e.TargetSite.Name, e.StackTrace));
            }

            return this;
        }

        public DbProvider Read(ref uint val)
        {
            try
            {
                val = (uint)((int)m_reader[m_col]);

                m_col++;
            }
            catch (Exception e)
            {
                EndExecuteQuery();
                Log.WriteLog(ELogLevel.LOG_ERROR, string.Format("{0};info[instance:{1}methed:{2}stack:{3}", e.Message, e.Source, e.TargetSite.Name, e.StackTrace));
            }
            return this;
        }

        public DbProvider Read(ref float val)
        {
            try
            {
                val = (float)m_reader[m_col];
                m_col++;
            }

            catch (Exception e)
            {
                EndExecuteQuery();
                Log.WriteLog(ELogLevel.LOG_ERROR, string.Format("{0};info[instance:{1}methed:{2}stack:{3}", e.Message, e.Source, e.TargetSite.Name, e.StackTrace));
            }
            return this;
        }

        public DbProvider Read(ref bool val)
        {
            try
            {
                val = (bool)m_reader[m_col];
                m_col++;
            }
            catch (Exception e)
            {
                EndExecuteQuery();
                Log.WriteLog(ELogLevel.LOG_ERROR, string.Format("{0};info[instance:{1}methed:{2}stack:{3}", e.Message, e.Source, e.TargetSite.Name, e.StackTrace));
            }
            return this;
        }

        public DbProvider Read(ref long val)
        {
            try
            {
                val = (long)m_reader[m_col];
                m_col++;
            }
            catch (Exception e)
            {
                EndExecuteQuery();
                Log.WriteLog(ELogLevel.LOG_ERROR, string.Format("{0};info[instance:{1}methed:{2}stack:{3}", e.Message, e.Source, e.TargetSite.Name, e.StackTrace));
            }
            return this;
        }

        public DbProvider Read(out string val)
        {
            val = null;
            try
            {
                val = m_reader[m_col].ToString();
                m_col++;
            }
            catch (Exception e)
            {
                EndExecuteQuery();
                Log.WriteLog(ELogLevel.LOG_ERROR, string.Format("{0};info[instance:{1}methed:{2}stack:{3}", e.Message, e.Source, e.TargetSite.Name, e.StackTrace));
            }
            return this;
        }

        public DbProvider Read(out DateTime? val)
        {
            val = null;
            try
            {
                string tempStr = m_reader[m_col].ToString();
                val = DateTime.Parse(tempStr);
                m_col++;
            }
            catch (Exception e)
            {
                EndExecuteQuery();
                Log.WriteLog(ELogLevel.LOG_ERROR, string.Format("{0};info[instance:{1}methed:{2}stack:{3}", e.Message, e.Source, e.TargetSite.Name, e.StackTrace));
            }
            return this;
        }

        public void KeepLive()
        {
            try
            {
                string sql = "select user()";
                ExecuteQuery(sql);
                EndExecuteQuery();
            }
            catch (Exception e)
            {
                Log.WriteLog(ELogLevel.LOG_ERROR, string.Format("{0};info[instance:{1}methed:{2}stack:{3}", e.Message, e.Source, e.TargetSite.Name, e.StackTrace));
            }
        }
    }
}
